﻿using Serilog;
using Serilog.Debugging;
using Serilog.Events;
using Serilog.Formatting.Json;
using Serilog.Sinks.Elasticsearch;
using Serilog.Sinks.File;
using Serilog.Sinks.SystemConsole.Themes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sustainalytics.GCCS
{
    public sealed class PdfGenerationSerilog:ILogPdf
    {
        public static Lazy<PdfGenerationSerilog> _lazyLog = new Lazy<PdfGenerationSerilog>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);
        private readonly ILogger _logger;


        public static PdfGenerationSerilog Log
        {
            get
            {
                return _lazyLog.Value;
            }
        }

        public void Ping()
        {
            var eventId = 1;
            _logger.Debug("Ping {eventId}", eventId);
        }

        public static PdfGenerationSerilog InitLog()
        {
            var log = new PdfGenerationSerilog();
            return log;

        }

        public PdfGenerationSerilog()
        {
            var loggerConfig = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console(theme: SystemConsoleTheme.Literate)
                  .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200")) // for the docker-compose implementation
                  {
                      IndexFormat = "testcompanyreport-{0:yyyy.MM.dd}",
                      AutoRegisterTemplate = true,
                      //BufferBaseFilename = "./buffer",
                      RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
                      FailureCallback = e => Console.WriteLine("Unable to submit event " + e.MessageTemplate),
                      EmitEventFailure = EmitEventFailureHandling.WriteToSelfLog |
                                         EmitEventFailureHandling.WriteToFailureSink |
                                         EmitEventFailureHandling.RaiseCallback,
                      FailureSink = new FileSink("../failuresPregenCompanyReport-" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", new JsonFormatter(), null)
                  });
            _logger = loggerConfig.CreateLogger();

            SelfLog.Enable(Console.Error);
        }
        internal void ApplicationStartError(Exception e)
        {
            var eventId = 11;
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error("ApplicationStartError {eventId}, {exception}", eventId, e.ToString());

        }
        internal void ApplicationStopError(Exception e)
        {
            var eventId = 12;
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error("ApplicationStopError {eventId}, {exception}", eventId, e.ToString());

        }

        internal void ApplicationUnhandledException(Exception e)
        {
            var eventId = 13;
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error("ApplicatioUnhandledError {eventId}, {exception}", eventId, e.ToString());
        }

        public void LogError(Exception ex)
        {
            _logger.Debug("Log error", ex.ToString());
        }

        public void LogError(string ex)
        {
            var eventId = 3;
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error("Log error {eventId}, {exception}", eventId, ex);

        }

        public void LogSuccess(string message)
        {
            LogPdfGeneration("PDF Generation Successful");
        }

        public void LogNullPdfRequest(string msg)
        {
            var eventId = 6;
            if (!_logger.IsEnabled(LogEventLevel.Information))
            {
                return;
            }
            _logger.Information("Log null pdf Request {eventId}, {message}", eventId, msg);
        }

        public void LogPdfRequestEmptyCompanies(string msg)
        {
            var eventId = 7;
            if (!_logger.IsEnabled(LogEventLevel.Information))
            {
                return;
            }
            _logger.Information("LogPdfRequestEmptyCompanies {eventId}, {message}", eventId, msg);
        }


        public void LogPdfGeneration(string msg)
        {
            var eventId = 8;
            if (!_logger.IsEnabled(LogEventLevel.Information))
            {
                return;
            }
            _logger.Information("LogPdfGeneration {eventId}, {message}", eventId, msg);


        }
        public void LogGenerationData(string msg)
        {
            LogPdfGeneration(msg);
        }


        public void CancelGeneration(string msg)
        {
            var eventId = 9;
            if (!_logger.IsEnabled(LogEventLevel.Information))
            {
                return;
            }
            _logger.Information("CancelGeneration {eventId}, {message}", eventId, msg);
        }

        public void Info(string s)
        {
            var eventId = 10;
            if (_logger.IsEnabled(LogEventLevel.Information))
            _logger.Information("Info {eventId}, {s}", eventId, s);
        }

        public void LogSummary(string msg)
        {
            LogPdfGeneration(msg);
        }
    }

    public interface ILogPdf
    {
        void LogGenerationData(string msg);
        void LogSummary(string msg);
        void LogError(string error);
        void LogSuccess(string message);
    }
    

}

